﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Hex2Data
{
    public partial class Form1 : Form
    {



        ListViewItem C2B = new ListViewItem("数组转换为文件", 2);
        ListViewItem B2C = new ListViewItem("文件转换为数组", 1);
        ListViewItem NIL = new ListViewItem("拖入数组或文件转换", 0);

        int maxppreread = 4096 * 1024;

        string targetfile=null;
        string targetfilename;
        string hexdata = null;
        string preread;
        bool disabledrag = false;
        MemoryStream ms=null;

        object lastdrag;
        public Form1()
        {
            InitializeComponent();
        }

        private void filedropview_DragEnter(object sender, DragEventArgs e)
        {
            infotext.Text = e.Data.GetFormats()[0];

            

            if (filedropview.Items[0] == C2B)
            {
                if (e.Data.GetDataPresent(DataFormats.Text))
                    e.Effect = DragDropEffects.Copy;
                else if (e.Data.GetData(DataFormats.FileDrop) != lastdrag)
                    e.Effect = DragDropEffects.Copy;
                else
                    e.Effect = DragDropEffects.None;
            }
            else if (filedropview.Items[0] == B2C)
            {
                if (e.Data.GetDataPresent(DataFormats.FileDrop))
                    e.Effect = DragDropEffects.Copy;
                else if (e.Data.GetData(DataFormats.Text) != lastdrag)
                    e.Effect = DragDropEffects.Copy;
                else
                    e.Effect = DragDropEffects.None;
            }
            else
                e.Effect = DragDropEffects.Copy;


        }

        private void Form1_Load(object sender, EventArgs e)
        {
            filedropview.Items.Add(NIL);
            filedropview.LargeImageList = imageList1;
            contextMenuStrip1.Items[0].Enabled = false;
            contextMenuStrip1.Items[2].Enabled = false;
            TopMost = true;
            //filesize.Text = System.IO.Path.GetTempPath();
            //filesize.Text = System.Environment.CurrentDirectory;
        }

        void data2file()
        {
            if (hexdata == null) return;
            int index = hexdata.IndexOf("0x");
            int value=0;
            int l=0;
            if (index != -1)
                ms=new MemoryStream();
            while (index != -1)
            {
                if (hexdata[index] == 'x')
                {
                    l = 1;
                    value = 0;
                }
                else if (l > 0)
                {
                    int tmp = hexdata[index]; ;
                    if (tmp <= '9' && tmp >= '0')
                    {
                        value <<= 4;
                        value += tmp - '0';
                        l++;
                    }
                    else if (tmp >= 'A' && tmp <= 'F')
                    {
                        value <<= 4;
                        value += tmp - 'A' + 10;
                        l++;
                    }
                    if (l == 3)
                    {
                        l = 0;
                        ms.WriteByte((byte)value);
                    }
                }
                index++;
                if (hexdata.Length == index) break;
                if (hexdata[index] == '}') break;
            }
            if (index != -1)
            {
                index = hexdata.IndexOf("[]");
                int point = -1;
                for(int i = index; i > 0; i--)
                {
                    if (hexdata[i] == '_')
                        if (point < i) point = i;
                    if(hexdata[i]==' ')
                    {
                        targetfilename = "";
                        for (int j = i + 1; j < index; j++)
                        {
                            if (j == point)
                                targetfilename = targetfilename + ".";
                            else
                                targetfilename = targetfilename + hexdata[j];
                        }
                        return;
                    }
                }
            }
        }

        private void filedropview_DragDrop(object sender, DragEventArgs e)
        {
            //filesize.Text=e.Data.GetData(typeof( string)) as string;
            var drops = (string[])e.Data.GetData(DataFormats.FileDrop, true);
            if (drops != null)
            {
                targetfile = drops[0];
                filedropview.Items[0] = B2C;
                FileInfo fi = new FileInfo(targetfile);
                filesize.Text=""+ fi.Length;
                preread = null;
                contextMenuStrip1.Items[0].Enabled = true;
                contextMenuStrip1.Items[2].Enabled = false;
                return;
            }
            var droptext = e.Data.GetData(DataFormats.Text, true) as string;
            if (droptext != null)
            {
                ms = null;
                targetfilename = "data";
                contextMenuStrip1.Items[0].Enabled = false;
                contextMenuStrip1.Items[2].Enabled = true;
                preread = null;
                hexdata = droptext;
                filedropview.Items[0] = C2B;
                data2file();
                if (ms != null)
                    filesize.Text = "" + ms.Length;
            }
        }

        SaveFileDialog sf = new SaveFileDialog();
        object getinfo()
        {
            if (filedropview.Items[0] == C2B)
            {

                string path = Environment.CurrentDirectory+"/"+targetfilename;

                if (ms != null)
                {
                    var fs=File.Create(path);
                    var data=ms.ToArray();
                    fs.Write(data, 0, data.Length);
                    fs.Flush();
                    fs.Close();
                }
                DataObject info = new DataObject(DataFormats.FileDrop,new string[] {path });
                return info;
            }
            else if (filedropview.Items[0] == B2C)
            {
                if (preread != null) return preread;
                var fs = File.Open(targetfile, FileMode.Open);
                byte[] buff = new byte[4096];
                if (fs.Length > maxppreread)
                {
                    sf.Filter = "所有文件|*.*";
                    if (sf.ShowDialog() == DialogResult.OK)
                    {
                        StreamWriter sb = new StreamWriter(new FileStream(sf.FileName, FileMode.OpenOrCreate));
                        sb.WriteLine("unsigned char {0}[]={{\r\n", Path.GetFileName(fs.Name).Replace('.','_'));
                        int len;
                        int count = 0;
                        do
                        {
                            len = fs.Read(buff, 0, 4096);
                            for (int i = 0; i < len; i++)
                            {
                                sb.Write("0x{0:X2},", buff[i]);
                                if (++count == 16)
                                {
                                    count = 0;
                                    sb.WriteLine();
                                }
                            }
                        } while (len == 4096);
                        sb.WriteLine("};");
                        sb.Flush();
                        sb.Close();
                        fs.Close();
                    }
                    return null;
                }
                else
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendFormat("#if 1\r\nunsigned char {0}[]={{\r\n", Path.GetFileName(fs.Name).Replace('.','_'));
                    int len;
                    int count = 0;
                    do
                    {
                        len = fs.Read(buff, 0, 4096);
                        for (int i = 0; i < len; i++)
                        {
                            sb.AppendFormat("0x{0:X2},", buff[i]);
                            if (++count == 16)
                            {
                                count = 0;
                                sb.AppendLine();
                            }
                        }
                    } while (len == 4096);
                    sb.AppendLine("};\r\n#endif");
                    fs.Close();
                    preread = sb.ToString();
                    return preread;
                }
            }

            return null;
        }

        private void filedropview_ItemDrag(object sender, ItemDragEventArgs e)
        {
            if (filedropview.Items[0] == C2B)
            {
                DoDragDrop(lastdrag=getinfo(), DragDropEffects.Move);
            }
            else if (filedropview.Items[0] == B2C)
            {
                string data = getinfo() as string;
                if(data!=null)
                    DoDragDrop(lastdrag=getinfo(), DragDropEffects.Copy);
            }
            

                
            
        }

        OpenFileDialog of = new OpenFileDialog();
        private void filedropview_DoubleClick(object sender, EventArgs e)
        {
            of.Filter = "所有文件|*.*";
            if (of.ShowDialog() == DialogResult.OK)
            {
                targetfile = of.FileName;
                filedropview.Items[0] = B2C;
                FileInfo fi = new FileInfo(targetfile);
                filesize.Text = "" + fi.Length;
                contextMenuStrip1.Items[0].Enabled = true;
                contextMenuStrip1.Items[2].Enabled = false;
                if (fi.Length<maxppreread)
                    getinfo();
            }
        }

        private void 复制数据ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string s=getinfo() as string;
            if(s!=null)
                Clipboard.SetData(DataFormats.Text, s);
        }

        private void filedropview_DragLeave(object sender, EventArgs e)
        {

        }

        private void 粘贴数据ToolStripMenuItem_Click_1(object sender, EventArgs e)
        {
            var data = Clipboard.GetData(DataFormats.Text) as string;
            if (data != null)
            {
                hexdata = data;
                ms = null;
                targetfilename = "data";
                contextMenuStrip1.Items[0].Enabled = false;
                contextMenuStrip1.Items[2].Enabled = true;
                preread = null;
                filedropview.Items[0] = C2B;
                data2file();
                if (ms != null) 
                filesize.Text = "" + ms.Length;
            }
        }

        private void 保存文件ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            sf.Filter = "所有文件|*.*";
            if (sf.ShowDialog() == DialogResult.OK)
            {
                string path = sf.FileName;
                if (ms != null)
                {
                    var fs = File.Create(path);
                    var data = ms.ToArray();
                    fs.Write(data, 0, data.Length);
                    fs.Flush();
                    fs.Close();
                }
            }
        }
    }
}
